/*
 * @Descripttion: 基于antd Input（原生input也可以，但需要稍微修改一下），通过keyUp事件监听输入的字符串，判断全角半角字符，限制最大输入长度的输入框
 */

import React, { Component } from 'react'
import { Input, Form } from 'antd';
const { TextArea } = Input

/**
 * 组件参数：
 * @param {string} type "input"输入框 "textarea" 文本框
 * @param {number} maxLength 最大输入长度（中文字符长度）
 * @param {object} formOptions 表单Form.Item的属性，当在表单中使用时传(antd 4.0)
 * @param {object} options 输入框其他属性
 */
export default class MaxLengthInput extends React.PureComponent {
    constructor(props) {
        super(props)
        this.state = {
            length: 0, // 字符串展示长度
        }
    }
    /**
     * keyUp事件监听输入字符串，控制最大长度
     * @param {Object} e 输入框原型
     * @param {number} maxLength 最大输入长度
     */
    limitLength = (e, max) => {
        const input = e.target;
        const split = input.value.split('');
        // 实际字节最大长度，全角字符为中文以及中文标点，占两个字节长度，半角为英文、数字、空格、英文标点等，占一个字节长度
        const maxLength = max * 2
        // 计算已输入的字节长度
        const map = split.map((s, i) => (input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128) ? 1 : 2);
        let n = 0;
        const charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
            if (accumulator === maxLength || accumulator === maxLength - 1) {
                // 累计长度达到设定最大长度时获取字符串最后的index，以删除index以后的字符
                n = index;
            }
            return accumulator + currentValue;
        });
        this.setState(() => {
            // 如果输入长度超出最大长度则显示最大长度
            let length = charLength < maxLength ? Math.ceil(charLength / 2) : max
            return {
                length
            }
        })
        if (charLength > maxLength) {
            // 删除超出部分字符串
            input.value = split.slice(0, n).join('');
        }
    }

    render() {
        let { length } = this.state
        let { type = 'input', maxLength = 0, options, formOptions } = this.props
        const isMaxLength = maxLength !== 0 // 是否限制最大长度
        const isForm = formOptions !== undefined // 是否是form表单中的输入框
        const option = {
            onKeyUp: isMaxLength ? (e) => this.limitLength(e, maxLength) : null,
            ...options
        }
        return (
            <div style={{ maxWidth: '80%' }}>
                {
                    isForm ?
                        (
                            <Form.Item {...formOptions}>
                                {type === 'input' ? <Input {...option} /> : <TextArea {...option} />}
                            </Form.Item>
                        )
                        :
                        (
                            <>
                                {type === 'input' ? <Input {...option} /> : <TextArea {...option} />}
                            </>

                        )
                }
                {
                    isMaxLength && <div className="lengthNum">
                        {length} / {maxLength}
                    </div>
                }
            </div>
        )
    }

}


class Preview extends Component {

    render() {
        return (
            <div>
                <div className='text_desc'>
                    input的示例
                </div>
                <MaxLengthInput maxLength={50}></MaxLengthInput>
                <div className='text_desc'>
                   textarea的示例
                </div>
                <MaxLengthInput type={'textarea'} maxLength={50}></MaxLengthInput>

            </div>
        )
    }
}

export const MaxInputPreview = Preview
